/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.rolgps.libns.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Observable;
import java.util.Observer;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.rolgps.libnstack.parser.ParserFactory;
import org.rolgps.libnstack.protocol.Message;
import org.rolgps.libnstack.protocol.MessageParser;

/**
 *
 * @author xeph
 */
public class SocketSender implements Runnable, Observer{

    private Socket outputSocket = null;
    private boolean doNotExitUntilThisBecomesFalse = true;
    private PrintWriter output = null;
    private MessageParser parser = ParserFactory.getDefaultParser();
    private BlockingQueue<Message> messageQueue = new LinkedBlockingQueue<Message>();
    private String[] filters = new String[0];

    @SuppressWarnings("unchecked")
    public SocketSender(Socket s) {
        this.outputSocket = s;
    }

    public synchronized void send(Message message){
        messageQueue.add(message);
    }

    private boolean hasAny(Message message, String[] filters){
        boolean result = false;
        for(String header : message.getHeader("sendTo")){
            for(String filter : filters){
                if(header.equals(filter)){
                    System.out.println("Filter found");
                    result = true;
                }
            }
        }
        return result;
    }
    public void run() {
        while(doNotExitUntilThisBecomesFalse){
            try {
                Message messageToSend = messageQueue.take();
                output = new PrintWriter(outputSocket.getOutputStream());

                    System.out.println("RTS");
                if(hasAny(messageToSend, filters)){
                    assert messageToSend != null;
                    String sending = parser.parseMessage(messageToSend);
                    System.out.println("SENDING: "+sending);
                    output.println(sending);
                    output.flush();
                }
            } catch (IOException ex) {
                Logger.getLogger(SocketSender.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InterruptedException ex) {
                Logger.getLogger(SocketSender.class.getName()).log(Level.SEVERE, null, ex);
            } finally{
                
            }
        }
        output.close();
    }

    public void update(Observable arg0, Object arg1) {
        if(arg1 instanceof Message){
            Message message = (Message) arg1;
            if(message.getHeader("type").length>0 &&
                    message.getHeader("type")[0].equals("handshake") &&
                    message.getTuple("service").length>0){
                this.filters=message.getTuple("service");
                System.out.println("HANDSHAKE received.");
            }else{
                System.out.println("Sending...");
                send(message);
            }
        }
    }

}
